package com.szeldon.pj.jps.exp;

import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;

import com.szeldon.pj.jps.data.store.SBAStore;
import com.szeldon.pj.jps.datastore.SimpleObject;
import com.szeldon.pj.jps.envs.ENVS;
import com.szeldon.pj.jps.qres.AbstractQueryResult;
import com.szeldon.pj.jps.qres.BagResult;
import com.szeldon.pj.jps.qres.QResStack;
import com.szeldon.pj.jps.visitor.ASTVisitor;

public class DiffBinaryExpression extends BinaryExpression {

	private static final Logger logger = Logger.getLogger(DiffBinaryExpression.class.getName());

	public DiffBinaryExpression(Expression leftExpression, Expression rightExpression) {
		super(leftExpression, rightExpression);
		// TODO Auto-generated constructor stub
	}

	@Override
	public int compareTo(SimpleObject object) throws IllegalStateException {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public String getValueAsString() {
		// TODO Auto-generated method stub
		return null;
	}

	public void accept(ASTVisitor astVisitor, ENVS envs, QResStack qResStack, SBAStore store) {

		astVisitor.accept(leftExpression);
		AbstractQueryResult leftResult = qResStack.pop();
		if (!(leftResult instanceof BagResult)) {
			throw new IllegalStateException("Diff expression must have a Bag result as left result."
					+ "Currently it's " + leftResult.getClass().getName() + ".");
		}

		astVisitor.accept(rightExpression);
		AbstractQueryResult rightResult = qResStack.pop();
		if (!(rightResult instanceof BagResult)) {
			throw new IllegalStateException("Diff expression must have a Bag result as right result."
					+ "Currently it's " + rightResult.getClass().getName() + ".");
		}

		BagResult leftResultBag = (BagResult) leftResult;
		BagResult rightResultBag = (BagResult) rightResult;
		Set<AbstractQueryResult> rightSet = rightResultBag.getElements();

		Set<AbstractQueryResult> resultSet = new HashSet<AbstractQueryResult>();
		for (AbstractQueryResult currentLeftResult : leftResultBag.getElements()) {
			boolean contains = rightSet.contains(currentLeftResult);
			if (!contains) {
				resultSet.add(currentLeftResult);
			}
		}

		qResStack.push(new BagResult(resultSet));
	}
}
